package marchsoft.modules.four.common.utils;

/**
 * @ClassName BaseUtils
 * @Author ZhuGuangLiang <786945363@qq.com>
 * @Date 2022/04/04 08:56
 */
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import marchsoft.enums.DataScopeEnum;
import marchsoft.enums.ResultEnum;
import marchsoft.exception.BadRequestException;
import marchsoft.modules.system.entity.Dept;
import marchsoft.modules.system.mapper.DeptMapper;
import marchsoft.modules.system.service.IDeptService;
import marchsoft.utils.RedisUtils;
import marchsoft.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * fetch
 *
 * @Author zhq
 * @Description 常用的工具类封装
 * @Data 17:11 2021/7/26
 */
@Slf4j
@Component
public class BaseUtils {
	@Autowired
	private IDeptService deptService;

	@Autowired
	private DeptMapper deptMapper;

	@Autowired
	private RedisUtils redisUtils;


	public static IDeptService deptServiceStatic;

	public static DeptMapper deptMapperStatic;

	public static RedisUtils redisUtilsStatic;

	@PostConstruct
	public void init() {
		deptMapperStatic = deptMapper;
		deptServiceStatic = deptService;
		redisUtilsStatic = redisUtils;
	}

	/**
	 * @param deptId
	 * @return boolean
	 * @description: 用户数据权限判断。有权限返回true，无权限报错
	 * @date: 2021/7/26 17:11
	 * @author: zhq
	 */
	public static void judgeCurrentDataScope(Long deptId) {
		if (!SecurityUtils.getDataScopeType().equals(DataScopeEnum.ALL.getValue()) && !SecurityUtils.getCurrentUserDataScope().contains(deptId)) {
			errorLog(ResultEnum.IDENTITY_NOT_POW, "无权限操作该部门用户数据", deptId);
			throw new BadRequestException("无权限操作该部门信息");
		}
	}

	/**
	 * @param num     数量
	 * @param operate 操作
	 * @param reason  原因
	 * @param data
	 * @return void
	 * @description: 异常日志处理
	 * @date: 2021/7/27 11:55
	 * @author: zhq
	 */
	public static void errorLog(Integer num, ResultEnum operate, String reason, Object data) {
		if (num <= 0) {
			log.error(StrUtil.format("【'" + operate.getMsg() + "'】操作人id：{}，参数：{}'" + reason + "'", SecurityUtils.getCurrentUserId(),
					data.toString()));
			throw new BadRequestException(reason);
		}

	}

	public static void errorLog(ResultEnum operate, String reason, Object data) {
		log.error(StrUtil.format("【'" + operate.getMsg() + "'】操作人id：{}，参数：{}'" + reason + "'", SecurityUtils.getCurrentUserId(),
				data.toString()));
		throw new BadRequestException(reason);
	}


	/**
	 * @return java.lang.Long 顶级部门id
	 * @Author zhuguangliang
	 * @Description 根据部门id获取顶级部门id;
	 * @Date 21:59 2021/07/30
	 * @Param [dept_id] 部门id
	 **/
	public static Long getTopDept(Long dept_id) {
		List<Dept> list = deptMapperStatic.selectList(new LambdaQueryWrapper<>());
		Long pid = null;
		Long id = null;
		Boolean bo = true;
		for (Dept dept : list) {
			if (dept.getId().equals(dept_id)) {
				pid = dept.getPid();
				if (pid == 0) {
					bo = false;
					id = dept.getId();
				}
				break;
			}
		}
		int i = 0;
		if (bo) {
			while (pid != 0 && i < list.size()) {
				if (list.get(i).getId().equals(pid)) {
					id = list.get(i).getId();
					pid = list.get(i).getPid();
				}
				i++;
			}
		}

		return id;
	}

	/**
	 * @return java.lang.Boolean
	 * @Author zhuguangliang
	 * @Description 判断对象的每个属性是否为空，如果忽略，请在if判断中加入
	 * @Date 14:22 2021/08/06
	 * @Param [object]
	 **/
	public static Boolean hasNull(Object object) {
		if (ObjectUtil.isNull(object)) {
			return false;
		}
		try {
			for (Field f : object.getClass().getDeclaredFields()) {
				f.setAccessible(true);
				if (Modifier.isFinal(f.getModifiers()) && Modifier.isStatic(f.getModifiers())) {
					continue;
				}
				if (f.getName().equals("id") || f.getName().equals("createTime")) {
					continue;
				}
				if (ObjectUtil.isEmpty(f.get(object))) {
					return true;
				}
				f.setAccessible(false);
			}

		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return false;
	}


	/**
	 * @param object
	 * @return java.lang.Boolean
	 * @description: 判断所有属性为null
	 * @date: 2021/8/9 11:16
	 * @author: zhq
	 */
	public static Boolean hasAllNull(Object object) {
		if (ObjectUtil.isNull(object)) {
			return false;
		}
		try {
			for (Field f : object.getClass().getDeclaredFields()) {
				f.setAccessible(true);
				if (Modifier.isFinal(f.getModifiers()) && Modifier.isStatic(f.getModifiers())) {
					continue;
				}
				if (ObjectUtil.isEmpty(f.get(object))) {
					return true;
				}
				f.setAccessible(false);
			}

		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return false;
	}


	/**
	 * @return java.lang.Boolean
	 * @Author zhuguangliang
	 * @Description 判断对象属性是否有空
	 * @Date 21:20 2021/08/10
	 * @Param [object, strings] Object：对象，strings：想要忽略判断的属性数组
	 **/
	public static Boolean hasNull(Object object, String... strings) {
		if (ObjectUtil.isNull(object)) {
			return false;
		}
		try {
			for (Field f : object.getClass().getDeclaredFields()) {
				boolean bo = false;
				f.setAccessible(true);
				if (Modifier.isFinal(f.getModifiers()) && Modifier.isStatic(f.getModifiers())) {
					continue;
				}
				for (String str : strings) {
					if (f.getName().equals(str)) {
						bo = true;
						break;
					}
				}
				if (bo) {
					continue;
				}
				if (ObjectUtil.isEmpty(f.get(object))) {
					log.info("对象的空字段为：" + f.getName());
					return true;
				}
				f.setAccessible(false);
			}

		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * @param deptId
	 * @return java.lang.Long
	 * @description: 获取顶级部门
	 * @date: 2021/8/23 10:38
	 * @author: zhq
	 */
	public static Long getDeptTopId(Long deptId) {
		Map<Long, Long> collect = deptMapperStatic.selectList(new LambdaQueryWrapper<Dept>().select(Dept::getId, Dept::getPid)).stream().collect(Collectors.toMap(Dept::getId, Dept::getPid));
		long a = deptId;
		while (collect.get(a) > 0) {
			a = collect.get(deptId);
		}
		return a;
	}


	public static String timeStampFormat(LocalDateTime time) {
		try {
			String format = "YYYY-MM-dd hh:mm:ss";
			// DateTimeFormatter.ofPattern方法根据指定的格式输出时间
			return time.format(DateTimeFormatter.ofPattern(format));
		} catch (Exception e) {
			return "";
		}
	}
}

